From d049abba4d1cb6297e380f4a7aa9f53a9d08454c Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Fri, 30 Mar 2007 17:02:46 +0100 Subject: [PATCH] hvm: Must increment RIP on INT3 instruction in SVM. Also tighten up checking of valid exception intercepts -- we should not vmexit on an exception we have not registered an interest in. Signed-off-by Tom Woller Signed-off-by Thomas Friebel Signed-off-by: Keir Fraser --- xen/arch/x86/hvm/svm/emulate.c | 4 +++- xen/arch/x86/hvm/svm/svm.c | 23 ++++++++++++----------- xen/arch/x86/hvm/vmx/vmx.c | 15 ++++----------- xen/include/asm-x86/hvm/svm/emulate.h | 1 + 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/xen/arch/x86/hvm/svm/emulate.c b/xen/arch/x86/hvm/svm/emulate.c index 824f36da91..57a293a273 100644 --- a/xen/arch/x86/hvm/svm/emulate.c +++ b/xen/arch/x86/hvm/svm/emulate.c @@ -373,6 +373,7 @@ MAKE_INSTR(HLT, 1, 0xf4); MAKE_INSTR(CLTS, 2, 0x0f, 0x06); MAKE_INSTR(LMSW, 3, 0x0f, 0x01, 0x00); MAKE_INSTR(SMSW, 3, 0x0f, 0x01, 0x00); +MAKE_INSTR(INT3, 1, 0xcc); static const u8 *opc_bytes[INSTR_MAX_COUNT] = { @@ -405,7 +406,8 @@ static const u8 *opc_bytes[INSTR_MAX_COUNT] = [INSTR_CLTS] = OPCODE_CLTS, [INSTR_HLT] = OPCODE_HLT, [INSTR_LMSW] = OPCODE_LMSW, - [INSTR_SMSW] = OPCODE_SMSW + [INSTR_SMSW] = OPCODE_SMSW, + [INSTR_INT3] = OPCODE_INT3 }; /* diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 315a79a6bf..64d97e78c9 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -2229,6 +2229,7 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs) unsigned long eip; struct vcpu *v = current; struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; + int inst_len; exit_reason = vmcb->exitcode; save_svm_cpu_user_regs(v, regs); @@ -2262,17 +2263,18 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs) break; case VMEXIT_EXCEPTION_DB: - if ( v->domain->debugger_attached ) - domain_pause_for_debugger(); - else - svm_inject_exception(v, TRAP_debug, 0, 0); + if ( !v->domain->debugger_attached ) + goto exit_and_crash; + domain_pause_for_debugger(); break; case VMEXIT_EXCEPTION_BP: - if ( v->domain->debugger_attached ) - domain_pause_for_debugger(); - else - svm_inject_exception(v, TRAP_int3, 0, 0); + if ( !v->domain->debugger_attached ) + goto exit_and_crash; + /* AMD Vol2, 15.11: INT3, INTO, BOUND intercepts do not update RIP. */ + inst_len = __get_instruction_length(v, INSTR_INT3, NULL); + __update_guest_eip(vmcb, inst_len); + domain_pause_for_debugger(); break; case VMEXIT_EXCEPTION_NM: @@ -2332,14 +2334,13 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs) svm_handle_invlpg(1, regs); break; - case VMEXIT_VMMCALL: { - int inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL); + case VMEXIT_VMMCALL: + inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL); ASSERT(inst_len > 0); HVMTRACE_1D(VMMCALL, v, regs->eax); __update_guest_eip(vmcb, inst_len); hvm_do_hypercall(regs); break; - } case VMEXIT_CR0_READ: svm_cr_access(v, 0, TYPE_MOV_FROM_CR, regs); diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 9d49f048c4..3856a31e96 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2511,16 +2511,10 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs) switch ( vector ) { case TRAP_debug: - if ( v->domain->debugger_attached ) - domain_pause_for_debugger(); - else - vmx_reflect_exception(v); - break; case TRAP_int3: - if ( v->domain->debugger_attached ) - domain_pause_for_debugger(); - else - vmx_reflect_exception(v); + if ( !v->domain->debugger_attached ) + goto exit_and_crash; + domain_pause_for_debugger(); break; case TRAP_no_device: vmx_do_no_device_fault(); @@ -2552,8 +2546,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs) vmx_reflect_exception(v); break; default: - vmx_reflect_exception(v); - break; + goto exit_and_crash; } break; } diff --git a/xen/include/asm-x86/hvm/svm/emulate.h b/xen/include/asm-x86/hvm/svm/emulate.h index 605e1cda5d..8a4e139d22 100644 --- a/xen/include/asm-x86/hvm/svm/emulate.h +++ b/xen/include/asm-x86/hvm/svm/emulate.h @@ -72,6 +72,7 @@ enum instruction_index { INSTR_CLTS, INSTR_LMSW, INSTR_SMSW, + INSTR_INT3, INSTR_MAX_COUNT /* Must be last - Number of instructions supported */ }; -- 2.30.2